package cn.cellcom.agent.online.iq.agent;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.cellcom.agent.common.AgentConstant;
import cn.cellcom.agent.common.AgentConstant.AG_SESSION_END_TYPE;
import cn.cellcom.agent.online.client.AgentClient;
import cn.cellcom.agent.online.client.Client;
import cn.cellcom.agent.online.client.ClientManager;
import cn.cellcom.agent.online.iq.AbstractChainedProcessor;
import cn.cellcom.agent.online.iq.Processor;
import cn.cellcom.agent.online.iq.ProcessorResult;
import cn.cellcom.agent.online.message.MessageConstant;
import cn.cellcom.agent.online.message.MessageConstant.ARCHIVE_EVENT;
import cn.cellcom.agent.online.message.MessageConstant.MESSAGE_EVENT;
import cn.cellcom.agent.online.message.MessageReceipt;
import cn.cellcom.agent.online.wrapper.AgSessionWrapper;
import cn.cellcom.agent.online.wrapper.SessionWrapper;
import cn.cellcom.agent.pojo.TUser;
import cn.cellcom.agent.struts.form.VisitorForm;
import cn.cellcom.jar.biz.AbstractBiz;

public class AgentInviteProcessor extends AbstractChainedProcessor {
	private Logger log = LoggerFactory.getLogger(this.getClass());

	public AgentInviteProcessor(Processor next) {
		super(next);
	}

	@Override
	public ProcessorResult doProcess(Map<String, AbstractBiz> bizs, Client client, VisitorForm cf) {
		AgentClient ac = (AgentClient) client;
		if (MessageConstant.MESSAGE_EVENT.AG_INVITE_AGENT.name().equals(cf.getEvent())
				|| MessageConstant.MESSAGE_EVENT.AG_TRANSFER2_AGENT.name().equals(cf.getEvent())) {
			log.info("[{}] invite agent [{}]", ac.getId(), cf.getValue());
			Client client2 = ClientManager.getInstance().getClient(cf.getValue());
			if (client2 == null) {
				return new ProcessorResult(false, this, "该坐席不在线");
			} else {
				AgentClient ac2 = (AgentClient) client2;
				SessionWrapper session = ac.getSession(cf.getSid());
				if (session == null) {
					return new ProcessorResult(false, this, "会话信息不正确");
				}
				// 记录会话的类型，坐席接入时可以决定如何处理
				session.setEvent(MessageConstant.MESSAGE_EVENT.valueOf(cf.getEvent()));
				if (MessageConstant.MESSAGE_EVENT.AG_INVITE_AGENT.name().equals(cf.getEvent())) {
					if (session.getAgsession(ac2.getId()) != null) {
						return new ProcessorResult(false, this, "该坐席已经在群中,无需再邀请");
					}
					// 归档
					ac.archive(session, ARCHIVE_EVENT.AG_INVITE_AGENT, ac2.getNickname());
					// 处理，发给坐席
					ac2.notifySessionInvite(session);
				} else {
					// 归档
					ac.archive(session, ARCHIVE_EVENT.AG_TRANSFER2_AGENT, ac2.getNickname());
					// 处理，发给坐席
					ac2.notifySessionTransfer(session);
				}
				// 记录内存数据
				ac2.getWaitingSessions().add(session);
				session.getInvitingAgents().add(ac2.getId());
			}
		} else if (MessageConstant.MESSAGE_EVENT.AG_ACCEPT_INVITE.name().equals(cf.getEvent())) {
			log.info("[{}] accept invite about cid [{}].", ac.getId(), cf.getCid());
			SessionWrapper session = ac.getSession(cf.getSid());// SessionManager.getInstance().getPool(ac.getPid()).getSession(cf.getSid());
			if (session == null) {
				return new ProcessorResult(true, this, "会话已结束，无需处理");
			}

			if (MessageConstant.MESSAGE_EVENT.AG_TRANSFER2_AGENT.equals(session.getEvent())) {
				//踢出原来的主持人
				session.getMastAgent().endSession(cf.getSid(), AG_SESSION_END_TYPE.AG_TRANSFER2_SUCC);
			} else {//邀请模式，通知主持人
				session.getMastAgent().notifySessionInviteAccepted(session, ac);
			}
			
			// 会话记录为群聊
			session.getSession().setType(AgentConstant.SESSION_TYPE.G.name());
			// 归档
			ac.archive(session, ARCHIVE_EVENT.AG_ACCEPT_INVITE, null);
			// 处理操作并通知发起坐席
			ac.receiveInvite(session);
			// 删除内存数据
			ac.getWaitingSessions().remove(session);
			session.getInvitingAgents().remove(ac.getId());
			//更新数据库
			ac.updateSessionDb(session.getSession());
		} else if (MessageConstant.MESSAGE_EVENT.AG_REJECT_INVITE.name().equals(cf.getEvent())) {
			log.info("[{}] reject invite about cid [{}].", ac.getId(), cf.getCid());
			SessionWrapper session = ac.getSession(cf.getSid());// SessionManager.getInstance().getPool(ac.getPid()).getSession(cf.getSid());
			if (session == null) {
				return new ProcessorResult(true, this, "会话已结束，无需处理");
			}
			// 归档
			ac.archive(session, ARCHIVE_EVENT.AG_REJECT_INVITE, null);
			// 处理
			session.getMastAgent().notifySessionInviteRejected(session, ac);
			// 删除内存数据
			ac.getWaitingSessions().remove(session);
			session.getInvitingAgents().remove(ac.getId());
		} else if (MessageConstant.MESSAGE_EVENT.AG_CANCEL_INVITE.name().equals(cf.getEvent())) {// TODO
		} else if ("existAgents".equals(cf.getEvent())) {// 查看群聊会话中的坐席列表
			SessionWrapper session = ac.getSession(cf.getSid());
			Collection<AgSessionWrapper> ags = session.getAgsessions().values();
			List<TUser> list = new ArrayList<TUser>();
			for (AgSessionWrapper ag : ags) {
				list.add(ag.getAgclient().getAgent());
			}
			return new ProcessorResult(true, this, list);
		} else if ("waitingList".equals(cf.getEvent())) {// 正在邀请我的会话
			log.info("[{}] get waiting list.", client.getId());
			Set<SessionWrapper> waitings = ac.getWaitingSessions();
			if (waitings != null) {
				for (SessionWrapper session : waitings) {
					SessionWrapper exist = ac.getSession(session.getId());
					if (exist != null) {
						if(exist.getEvent().equals(MESSAGE_EVENT.AG_TRANSFER2_AGENT)) {
							ac.notifySessionTransfer(session);
						} else {
							ac.notifySessionInvite(session);
						}
					} else {
						ac.getWaitingSessions().remove(session);
					}
				}
			}
		}
		return new ProcessorResult(true, this, new MessageReceipt(cf.getId(), true));
	}

	@Override
	public boolean isAcceptable(VisitorForm cf) {
		return "waitingList".equals(cf.getEvent()) || "existAgents".equals(cf.getEvent())
				|| MessageConstant.MESSAGE_EVENT.AG_TRANSFER2_AGENT.name().equals(cf.getEvent())
				|| MessageConstant.MESSAGE_EVENT.AG_INVITE_AGENT.name().equals(cf.getEvent())
				|| MessageConstant.MESSAGE_EVENT.AG_ACCEPT_INVITE.name().equals(cf.getEvent())
				|| MessageConstant.MESSAGE_EVENT.AG_CANCEL_INVITE.name().equals(cf.getEvent())
				|| MessageConstant.MESSAGE_EVENT.AG_REJECT_INVITE.name().equals(cf.getEvent());
	}
}
